import { Injectable } from '@nestjs/common';
import { DbService } from 'apps/admin/src/db/db.service';
import CreateDto from './dto/create.dto';
import * as dayjs from 'dayjs';
import UpdateDto from './dto/update.dto';
import { Role } from '@app/db/common/entity/Role';
import PageDto from './dto/page.dto';
import { FindOptionsWhere } from 'typeorm';

@Injectable()
export class RoleService {
    constructor(
        private readonly db:DbService
    ){}
    

    async options(memberId:number) {
        return this.db.role.find({creatorId : memberId, enable : true}, {id : true, name : true})
    }

    async page(dto:PageDto, memberId:number) {
        let result:PaginationResult<Role> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<Role> = {
            creatorId : memberId
        }

        result.total = await this.db.role.count(where)

        if(result.total > 0) {
            result.rows = await this.db.role.pagination(dto.pageNo, dto.pageSize, where, null, {sort : 'DESC', id : 'DESC'})
        }

        return result
    }

    
    async add(dto:CreateDto, memberId:number) {

        if(true == await this.db.role.isExistsByWhere({name : dto.name, creatorId : memberId})) throw new Error('已存在相同的名称')

        return this.db.role.insert({...dto, creatorId : memberId, createTime : dayjs().unix()})
    }

    async update(dto:UpdateDto, memberId:number) {
        let fields = Object.keys(dto) as (keyof Role)[]
        if(fields.length == 0) return true

        const row = await this.db.role.findOne({ id : dto.id })
        
        if(!row || row.creatorId != memberId) return false

        let updateData:KeyToValueType<Role> = {}

        delete row.creatorId

        for(let k in row) {
            if(k in dto) {
                if(k == 'menus') {
                    if(row[k] && dto[k]) {
                        const m1 = [...row[k]]
                        const m2 = [...dto[k]]
                        m1.sort()
                        m2.sort()
                        if(JSON.stringify(m1) == JSON.stringify(m2)) continue
                    }
                    
                }else {
                    if(row[k] == dto[k]) continue
                }
    
                updateData[k] = dto[k]
            }
            
        }

        if(Object.keys(updateData).length == 0) return true

        if(updateData.name && (true == await this.db.role.isExistsByWhere({name : updateData.name, creatorId : memberId}))) throw new Error('已存在相同的名称')

        return this.db.role.update({id : dto.id}, updateData)
    }

    async del(id:number, memberId:number) {
        let role = await this.db.role.findOne({ id }, ['creatorId'])
        if(!role || role.creatorId != memberId) return
        return this.db.role.delete({id : id})
    }
}
